#ifndef HSE_VBYTE_H
#define HST_VBYTE_H
#include "types.h"
#include "common.h"

namespace hse {
namespace util {

#define VB_HEAD 0x80
#define VB_HEAD_MOV 0x7F

class VByte {
public:
	//decode from src, get a SINGLE unit
	template <class T>
	inline static UINT DecodeAUnit(T *dest, UBYTE src[]) {
		UINT i = 0;
		*dest = 0;
		while (*src < VB_HEAD) {
			*dest = *dest << 7 | *src++;
			i++;
		}
		*dest = *dest << 7 | (*src & VB_HEAD_MOV);
		return ++i; 
	}

	//decode size byte, return decoded count
	template <class T>
	static UINT DecodeAll(T *dest, UBYTE src[], UINT size) {
		UINT i = 0, l = 0;
		while (i < size) {
			i += DecodeAUnit(dest++, src + i);
			l++;
		}
		return l;
	}

	template <class T>
	inline static UINT EncodeAUnit(UBYTE *dest, T src) {
		T t = src >> 7;
		UINT l = 1;
		while (t) {
			dest++;
			t >>= 7;
			l++;
		}
		*dest-- = VB_HEAD | (UBYTE (src));
		src >>= 7;
		while (src) {
			*dest-- = VB_HEAD_MOV & (UBYTE (src));
			src >>= 7;
		}
		return l;
	}

	//encode count src, return byte used
	template <class T>
	static UINT EncodeAll(UBYTE *dest, T *src, UINT count) {
		UINT l = 0;
		while (count--) {
			l += EncodeAUnit(dest + l, *src++);
		}
		return l;
	}

};


} //end of namespace util
} //end of namespace hse
#endif